home *** CD-ROM | disk | FTP | other *** search
/ Openstep 4.2 (Developer) / Openstep Developer 4.2.iso / NextDeveloper / Source / GNU / uucp / Uucp.framework / unix.subproj / opensr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-09  |  6.0 KB  |  253 lines

  1. /* opensr.c
  2.    Open files for sending and receiving.
  3.  
  4.    Copyright (C) 1991, 1992, 1993 Ian Lance Taylor
  5.  
  6.    This file is part of the Taylor UUCP package.
  7.  
  8.    This program is free software; you can redistribute it and/or
  9.    modify it under the terms of the GNU General Public License as
  10.    published by the Free Software Foundation; either version 2 of the
  11.    License, or (at your option) any later version.
  12.  
  13.    This program is distributed in the hope that it will be useful, but
  14.    WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.    General Public License for more details.
  17.  
  18.    You should have received a copy of the GNU General Public License
  19.    along with this program; if not, write to the Free Software
  20.    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21.  
  22.    The author of the program may be contacted at ian@airs.com or
  23.    c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144.
  24.    */
  25.  
  26. #include "uucp.h"
  27.  
  28. #include "uudefs.h"
  29. #include "uuconf.h"
  30. #include "system.h"
  31. #include "sysdep.h"
  32.  
  33. #include <errno.h>
  34.  
  35. #if HAVE_TIME_H
  36. #include <time.h>
  37. #endif
  38.  
  39. #if HAVE_FCNTL_H
  40. #include <fcntl.h>
  41. #else
  42. #if HAVE_SYS_FILE_H
  43. #include <sys/file.h>
  44. #endif
  45. #endif
  46.  
  47. #ifndef O_RDONLY
  48. #define O_RDONLY 0
  49. #define O_WRONLY 1
  50. #define O_RDWR 2
  51. #endif
  52.  
  53. #ifndef O_NOCTTY
  54. #define O_NOCTTY 0
  55. #endif
  56.  
  57. #ifndef FD_CLOEXEC
  58. #define FD_CLOEXEC 1
  59. #endif
  60.  
  61. #ifndef time
  62. extern time_t time ();
  63. #endif
  64.  
  65. /* Open a file to send to another system, and return the mode and
  66.    the size.  */
  67.  
  68. openfile_t
  69. esysdep_open_send (qsys, zfile, fcheck, zuser)
  70.      const struct uuconf_system *qsys;
  71.      const char *zfile;
  72.      boolean fcheck;
  73.      const char *zuser;
  74. {
  75.   struct stat s;
  76.   openfile_t e;
  77.   int o;
  78.   
  79.   if (fsysdep_directory (zfile))
  80.     {
  81.       ulog (LOG_ERROR, "%s: is a directory", zfile);
  82.       return EFILECLOSED;
  83.     }
  84.  
  85. #if USE_STDIO
  86.   e = fopen (zfile, BINREAD);
  87.   if (e == NULL)
  88.     {
  89.       ulog (LOG_ERROR, "fopen (%s): %s", zfile, strerror (errno));
  90.       return NULL;
  91.     }
  92.   o = fileno (e);
  93. #else
  94.   e = open ((char *) zfile, O_RDONLY | O_NOCTTY, 0);
  95.   if (e == -1)
  96.     {
  97.       ulog (LOG_ERROR, "open (%s): %s", zfile, strerror (errno));
  98.       return -1;
  99.     }
  100.   o = e;
  101. #endif
  102.  
  103.   if (fcntl (o, F_SETFD, fcntl (o, F_GETFD, 0) | FD_CLOEXEC) < 0)
  104.     {
  105.       ulog (LOG_ERROR, "fcntl (FD_CLOEXEC): %s", strerror (errno));
  106.       (void) ffileclose (e);
  107.       return EFILECLOSED;
  108.     }
  109.  
  110.   if (fstat (o, &s) == -1)
  111.     {
  112.       ulog (LOG_ERROR, "fstat: %s", strerror (errno));
  113.       s.st_mode = 0666;
  114.     }
  115.  
  116.   /* We have to recheck the file permission, although we probably
  117.      checked it already, because otherwise there would be a window in
  118.      which somebody could change the contents of a symbolic link to
  119.      point to some file which was only readable by uucp.  */
  120.   if (fcheck)
  121.     {
  122.       if (! fsuser_access (&s, R_OK, zuser))
  123.     {
  124.       ulog (LOG_ERROR, "%s: %s", zfile, strerror (EACCES));
  125.       (void) ffileclose (e);
  126.       return EFILECLOSED;
  127.     }
  128.     }
  129.  
  130.   return e;
  131. }
  132.  
  133. /* Get a temporary file name to receive into.  We use the ztemp
  134.    argument to pick the file name, so that we restart the file if the
  135.    transmission is aborted.  */
  136.  
  137. char *
  138. zsysdep_receive_temp (qsys, zto, ztemp, frestart)
  139.      const struct uuconf_system *qsys;
  140.      const char *zto;
  141.      const char *ztemp;
  142.      boolean frestart;
  143. {
  144.   if (frestart
  145.       && ztemp != NULL
  146.       && *ztemp == 'D'
  147.       && strcmp (ztemp, "D.0") != 0)
  148.     return zsappend3 (".Temp", qsys->uuconf_zname, ztemp);
  149.   else
  150.     return zstemp_file (qsys);
  151. }  
  152.  
  153. /* The number of seconds in one week.  We must cast to long for this
  154.    to be calculated correctly on a machine with 16 bit ints.  */
  155. #define SECS_PER_WEEK ((long) 7 * (long) 24 * (long) 60 * (long) 60)
  156.  
  157. /* Open a temporary file to receive into.  This should, perhaps, check
  158.    that we have write permission on the receiving directory, but it
  159.    doesn't.  */
  160.  
  161. openfile_t
  162. esysdep_open_receive (qsys, zto, ztemp, zreceive, pcrestart)
  163.      const struct uuconf_system *qsys;
  164.      const char *zto;
  165.      const char *ztemp;
  166.      const char *zreceive;
  167.      long *pcrestart;
  168. {
  169.   int o;
  170.   openfile_t e;
  171.  
  172.   /* If we used the ztemp argument in zsysdep_receive_temp, above,
  173.      then we will have a name consistent across conversations.  In
  174.      that case, we may have already received some portion of this
  175.      file.  */
  176.   o = -1;
  177.   if (pcrestart != NULL)
  178.     *pcrestart = -1;
  179.   if (pcrestart != NULL
  180.       && ztemp != NULL
  181.       && *ztemp == 'D'
  182.       && strcmp (ztemp, "D.0") != 0)
  183.     {
  184.       o = open ((char *) zreceive, O_WRONLY);
  185.       if (o >= 0)
  186.     {
  187.       struct stat s;
  188.  
  189.       /* For safety, we insist on the file being less than 1 week
  190.          old.  This can still catch people, unfortunately.  I
  191.          don't know of any good solution to the problem of old
  192.          files hanging around.  If anybody has a file they want
  193.          restarted, and they know about this issue, they can touch
  194.          it to bring it up to date.  */
  195.       if (fstat (o, &s) < 0
  196.           || s.st_mtime + SECS_PER_WEEK < time ((time_t *) NULL))
  197.         {
  198.           (void) close (o);
  199.           o = -1;
  200.         }
  201.       else
  202.         {
  203.           DEBUG_MESSAGE1 (DEBUG_SPOOLDIR,
  204.                   "esysdep_open_receive: Reusing %s",
  205.                   zreceive);
  206.           *pcrestart = (long) s.st_size;
  207.         }
  208.     }
  209.     }
  210.  
  211.   if (o < 0)
  212.     o = creat ((char *) zreceive, IPRIVATE_FILE_MODE);
  213.  
  214.   if (o < 0)
  215.     {
  216.       if (errno == ENOENT)
  217.     {
  218.       if (! fsysdep_make_dirs (zreceive, FALSE))
  219.         return EFILECLOSED;
  220.       o = creat ((char *) zreceive, IPRIVATE_FILE_MODE);
  221.     }
  222.       if (o < 0)
  223.     {
  224.       ulog (LOG_ERROR, "creat (%s): %s", zreceive, strerror (errno));
  225.       return EFILECLOSED;
  226.     }
  227.     }
  228.  
  229.   if (fcntl (o, F_SETFD, fcntl (o, F_GETFD, 0) | FD_CLOEXEC) < 0)
  230.     {
  231.       ulog (LOG_ERROR, "fcntl (FD_CLOEXEC): %s", strerror (errno));
  232.       (void) close (o);
  233.       (void) remove (zreceive);
  234.       return EFILECLOSED;
  235.     }
  236.  
  237. #if USE_STDIO
  238.   e = fdopen (o, (char *) BINWRITE);
  239.  
  240.   if (e == NULL)
  241.     {
  242.       ulog (LOG_ERROR, "fdopen (%s): %s", zreceive, strerror (errno));
  243.       (void) close (o);
  244.       (void) remove (zreceive);
  245.       return EFILECLOSED;
  246.     }
  247. #else
  248.   e = o;
  249. #endif
  250.  
  251.   return e;
  252. }
  253.